import {
  BadRequestException,
  HttpException,
  HttpStatus,
  Inject,
  Injectable,
  Logger,
} from '@nestjs/common';
import { PrismaService } from 'src/modules/prisma/prisma.service';
import { RedisService } from 'src/modules/redis/redis.service';
import {
  RegisterUserDto,
  UpdateUserDto,
  UpdateUserPasswordDto,
} from './user.dto';
import { EmailService } from 'src/modules/email/email.service';
import { JwtService } from '@nestjs/jwt';
import { generateVerificationCode } from 'src/utils';

@Injectable()
export class UserService {
  @Inject(EmailService)
  private emailService: EmailService;

  @Inject(PrismaService)
  private readonly prismaService: PrismaService;

  @Inject(RedisService)
  private redisService: RedisService;

  @Inject(JwtService)
  private jwtService: JwtService;

  private logger = new Logger();

  async generateVerifyCode(email: string) {
    const code = Math.floor(Math.random() * 1000000).toString();
    await this.redisService.set(`captcha_${email}`, code, 60 * 5);

    try {
      await this.emailService.sendMail({
        to: email,
        subject: '注册验证码',
        html: `<p>你的注册验证码是 ${code}</p>`,
      });
      return {
        success: true,
        message: '验证码已发送至邮箱',
      };
    } catch (error) {
      console.error('发送验证码失败', error);
      throw new HttpException(
        '发送验证码失败',
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  async create(user: RegisterUserDto) {
    const captcha = await this.redisService.get(`captcha_${user.email}`);

    if (!captcha) {
      throw new HttpException('验证码已过期', HttpStatus.BAD_REQUEST);
    }

    if (user.captcha !== captcha) {
      throw new HttpException('验证码错误', HttpStatus.BAD_REQUEST);
    }

    const foundUser = await this.prismaService.user.findUnique({
      where: {
        username: user.username,
      },
    });

    if (foundUser) {
      throw new HttpException('用户名已存在', HttpStatus.BAD_REQUEST);
    }

    try {
      const newUser = await this.prismaService.user.create({
        data: {
          username: user.username,
          password: user.password,
          nickName: user.nickName,
          email: user.email,
        },
        select: {
          id: true,
          username: true,
          nickName: true,
          email: true,
          headPic: true,
          createTime: true,
        },
      });
      return {
        success: true,
        message: '用户注册成功',
        user: newUser,
      };
    } catch (e) {
      this.logger.error(e, UserService);
      return {
        success: false,
        message: '用户注册失败' + e.message,
      };
    }
  }

  async login(loginUser) {
    const foundUser = await this.prismaService.user.findUnique({
      where: {
        username: loginUser.username,
      },
    });

    if (!foundUser) {
      throw new HttpException('用户不存在', HttpStatus.BAD_REQUEST);
    }

    if (loginUser.password !== foundUser.password) {
      throw new HttpException('密码错误', HttpStatus.BAD_REQUEST);
    }

    const token = this.jwtService.sign(
      {
        userId: foundUser.id,
        username: foundUser.username,
      },
      {
        expiresIn: '7d',
      },
    );

    delete foundUser.password;
    return { user: foundUser, token, message: '登录成功' };
  }

  async findUserDetailById(userId: number) {
    return await this.prismaService.user.findUnique({
      where: {
        id: userId,
      },
      select: {
        id: true,
        username: true,
        nickName: true,
        email: true,
        headPic: true,
        createTime: true,
      },
    });
  }

  async generateUpdateInfoCaptcha(email: string) {
    if (!email) {
      throw new BadRequestException('邮箱地址不能为空');
    }

    const code = generateVerificationCode();

    await this.redisService.set(`update_info_captcha_${email}`, code, 10 * 60);

    await this.emailService.sendMail({
      to: email,
      subject: '修改信息验证码',
      html: `<p>你的修改信息验证码是 ${code}</p>`,
    });
    return '发送成功';
  }

  async update(userId: number, updateUserDto: UpdateUserDto) {
    const captcha = await this.redisService.get(
      `update_info_captcha_${updateUserDto.email}`,
    );

    if (!captcha) {
      throw new HttpException('验证码已失效', HttpStatus.BAD_REQUEST);
    }

    if (updateUserDto.captcha !== captcha) {
      throw new HttpException('验证码不正确', HttpStatus.BAD_REQUEST);
    }

    const foundUser = await this.prismaService.user.findUnique({
      where: {
        id: userId,
      },
    });

    if (updateUserDto.nickName) {
      foundUser.nickName = updateUserDto.nickName;
    }
    if (updateUserDto.headPic) {
      foundUser.headPic = updateUserDto.headPic;
    }
    try {
      await this.prismaService.user.update({
        where: {
          id: userId,
        },
        data: foundUser,
      });

      return '信息修改成功';
    } catch (e) {
      this.logger.error(e, UserService);
      return '用户信息修改失败';
    }
  }

  async generateUpdatePasswordCaptcha(email: string) {
    if (!email) {
      throw new BadRequestException('邮箱地址不能为空');
    }
    const code = generateVerificationCode();

    await this.redisService.set(
      `update_password_captcha_${email}`,
      code,
      10 * 60,
    );

    await this.emailService.sendMail({
      to: email,
      subject: '更改密码验证码',
      html: `<p>你的更改密码验证码是 ${code}</p>`,
    });
    return {
      success: true,
      message: '验证码已发送至邮箱',
    };
  }

  async updatePassword(passwordDto: UpdateUserPasswordDto) {
    const captcha = await this.redisService.get(
      `update_password_captcha_${passwordDto.email}`,
    );

    if (!captcha) {
      throw new HttpException('验证码已失效', HttpStatus.BAD_REQUEST);
    }

    if (passwordDto.captcha !== captcha) {
      throw new HttpException('验证码不正确', HttpStatus.BAD_REQUEST);
    }

    const foundUser = await this.prismaService.user.findUnique({
      where: {
        username: passwordDto.username,
      },
    });

    foundUser.password = passwordDto.password;

    try {
      await this.prismaService.user.update({
        where: {
          id: foundUser.id,
        },
        data: foundUser,
      });
      return {
        success: true,
        message: '密码修改成功',
      };
    } catch (e) {
      this.logger.error(e, UserService);
      return '密码修改失败';
    }
  }

  async getFriendship(userId: number) {
    const friendshipList = await this.prismaService.friendship.findMany({
      where: {
        OR: [
          {
            userId,
          },
          {
            friendId: userId,
          },
        ],
      },
    });

    const set = new Set<number>();
    for (let i = 0; i < friendshipList.length; i++) {
      set.add(friendshipList[i].userId);
      set.add(friendshipList[i].friendId);
    }
    // 好友的ID
    const friendIds = [...set].filter((item) => item !== userId);
    console.log(friendIds);
    const res = [];
    for (let i = 0; i < friendIds.length; i++) {
      const user = await this.prismaService.user.findUnique({
        where: {
          id: friendIds[i],
        },
        select: {
          id: true,
          username: true,
          nickName: true,
          email: true,
        },
      });
      res.push(user);
    }

    return res;
  }
}
